package cc.magicjson.summary.errors.mybatis.generator;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

public class MergeStatementPlugin extends PluginAdapter {

    @Override
    public boolean sqlMapInsertElementGenerated(XmlElement documentElement, IntrospectedTable introspectedTable) {
        // 仅在表中存在主键时生成 MERGE INTO（无主键无法实现 MERGE）
        if (!introspectedTable.hasPrimaryKeyColumns()) {
            return true;
        }

        // 创建新的 <insert> 节点
        XmlElement mergeElement = new XmlElement("insert");
        mergeElement.addAttribute(new Attribute("id", "mergeSelective"));
        mergeElement.addAttribute(new Attribute("parameterType", introspectedTable.getBaseRecordType()));

        // 构建 MERGE INTO 动态 SQL
        String mergeSql = buildMergeIntoSql(introspectedTable);
        mergeElement.addElement(new TextElement(mergeSql));

        // 将新节点添加到 XML 文档末尾
        documentElement.addElement(mergeElement);
        return true;
    }

    private String buildMergeIntoSql(IntrospectedTable table) {
        String tableName = table.getFullyQualifiedTableNameAtRuntime();
        List<IntrospectedColumn> primaryKeys = table.getPrimaryKeyColumns();
        List<IntrospectedColumn> allColumns = table.getAllColumns();

        StringBuilder sb = new StringBuilder();
        sb.append("<![CDATA[");
        sb.append("MERGE INTO ").append(tableName).append(" USING (");
        sb.append("SELECT ");
        // 动态拼接参数映射（如 #{id}, #{name}）
        for (IntrospectedColumn column : allColumns) {
            sb.append("#{").append(column.getJavaProperty()).append("} AS ").append(column.getActualColumnName()).append(", ");
        }
        sb.delete(sb.length() - 2, sb.length()); // 移除最后一个逗号
        sb.append(" FROM DUAL) SRC ");
        sb.append("ON (");
        // 拼接 ON 条件（主键匹配）
        for (IntrospectedColumn pk : primaryKeys) {
            sb.append(tableName).append(".").append(pk.getActualColumnName()).append(" = SRC.").append(pk.getActualColumnName()).append(" AND ");
        }
        sb.delete(sb.length() - 5, sb.length()); // 移除末尾的 "AND "
        sb.append(") ");
        // WHEN MATCHED 更新非主键字段
        sb.append("WHEN MATCHED THEN UPDATE SET ");
        for (IntrospectedColumn column : allColumns) {
            if (!primaryKeys.contains(column)) {
                sb.append(column.getActualColumnName()).append(" = SRC.").append(column.getActualColumnName()).append(", ");
            }
        }
        sb.delete(sb.length() - 2, sb.length());
        // WHEN NOT MATCHED 插入所有字段
        sb.append(" WHEN NOT MATCHED THEN INSERT (");
        for (IntrospectedColumn column : allColumns) {
            sb.append(column.getActualColumnName()).append(", ");
        }
        sb.delete(sb.length() - 2, sb.length());
        sb.append(") VALUES (");
        for (IntrospectedColumn column : allColumns) {
            sb.append("SRC.").append(column.getActualColumnName()).append(", ");
        }
        sb.delete(sb.length() - 2, sb.length());
        sb.append(")]]>");
        return sb.toString();
    }

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }
}
